<?php


namespace App\Services\Company\Services;

use App\Businesses\BusinessState;
use App\Events\UserRegisterEvent;
use App\Events\UserVideoWatchedEvent;
use App\Exceptions\ServiceException;
use App\Models\CompanyAdministratorRoleRelation;
use App\Services\Base\Interfaces\ConfigServiceInterface;
use App\Services\Base\Services\ConfigService;
use App\Services\Business\Models\Anthology;
use App\Services\Business\Models\Article;
use App\Services\Business\Models\Combo;
use App\Services\Business\Models\Course;
use App\Services\Business\Models\Favorite;
use App\Services\Business\Models\Follow;
use App\Services\Business\Models\Note;
use App\Services\Business\Models\Paper;
use App\Services\Business\Models\Question;
use App\Services\Business\Models\Solution;
use App\Services\Business\Models\ThumbsUp;
use App\Services\Business\Models\UserPaper;
use App\Services\Business\Models\Video;
use App\Services\Company\Interfaces\UserServiceInterface;
use App\Services\Member\Interfaces\UserInviteBalanceServiceInterface;
use App\Services\Member\Models\Address;
use App\Services\Member\Models\FavoriteCategory;
use App\Services\Member\Models\User;
use App\Services\Member\Models\UserAnthology;
use App\Services\Member\Models\UserArticle;
use App\Services\Member\Models\UserCombo;
use App\Services\Member\Models\UserCourse;
use App\Services\Member\Models\UserGroup;
use App\Services\Member\Models\UserLoginRecord;
use App\Services\Member\Models\UserProfile;
use App\Services\Member\Models\UserRole;
use App\Services\Member\Models\UserVideoWatchRecord;
use App\Services\Member\Models\UserWatchStat;
use App\Services\Member\Services\UserInviteBalanceService;
use App\Services\Order\Models\UserRedeemCode;
use App\Services\Other\Models\UserPrize;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;


class UserService implements UserServiceInterface
{
    /**
     * @var ConfigService
     */
    protected $configService;
    protected $businessState;

    public function __construct(ConfigServiceInterface $configService, BusinessState $businessState)
    {
        $this->configService = $configService;
        $this->businessState = $businessState;
    }

    /**
     * @return array
     */
    public function currentUser(): array
    {
        return $this->find(Auth::id(), ['role']);
    }


    /**
     * @param string $mobile
     * @return mixed
     */
    public function findMobile(string $mobile)
    {
        return  User::whereMobile($mobile)->first();

    }




    /**
     * @param string $mobile
     * @param string $password
     *
     * @return array
     */
    public function passwordLogin(string $mobile, string $password): array
    {
        $user = User::whereMobile($mobile)->first();
        if (!$user) {
            return [];
        }
         if (!Hash::check($password, $user->password)) {
              return [];
          }

        return $user->toArray();
    }

    /**
     * @param int $userId
     * @param string $oldPassword
     * @param string $newPassword
     *
     * @throws \Exception
     */
    public function resetPassword(int $userId, string $oldPassword, string $newPassword): void
    {
        $user = User::findOrFail($userId);
        if ($oldPassword && !Hash::check($oldPassword, $user->password)) {
            throw new ServiceException(__('原密码错误'));
        }
        $this->changePassword($user->id, $newPassword);
    }

    /**
     * 找回密码
     *
     * @param $mobile string 手机号
     * @param $password string 新密码
     */
    public function findPassword(string $mobile, string $password): void
    {
        $user = User::whereMobile($mobile)->firstOrFail();
        $this->changePassword($user->id, $password);
    }

    /**
     * @param int $userId
     * @param string $password
     */
    public function changePassword(int $userId, string $password): void
    {
        User::whereId($userId)->update([
            'password' => Hash::make($password),
            'is_password_set' => 1,
        ]);
    }

    /**
     * @param string $avatar
     * @param string $name
     * @return array
     * @throws \Exception
     */
    public function createWithoutMobile(string $avatar = '', string $name = ''): array
    {
        $user = User::create([
            'uuid'=> 'zs'.time().rand(1000, 9999),
            'avatar' => $avatar ?: $this->configService->getMemberDefaultAvatar(),
            'nick_name' => $name ?? Str::random(16),
            'mobile' => random_int(2, 9) . random_int(1000, 9999) . random_int(1000, 9999),
            'password' => Hash::make(Str::random(16)),
            'is_lock' => $this->configService->getMemberLockStatus(),
            'is_active' => $this->configService->getMemberActiveStatus(),
            'role_id' => 0,
            'expired_at' => Carbon::now(),
            'is_set_nickname' => 0,
        ]);

        event(new UserRegisterEvent($user->id));

        return $user->toArray();
    }


    public function createWithMobile(string $mobile, string $password, string $name, string $avatar = '')
    {

        //这里会同步创建前端的用户
        $user =User::query()->where('mobile',$mobile)->first();
        if (!$user) {
            $user=  User::create([
                'uuid'=> 'zs'.time().rand(1000, 9999),
                'avatar' => $avatar ?: $this->configService->getMemberDefaultAvatar(),
                'nick_name' => $name ?: $mobile,
                'mobile' => $mobile,
                'password' => Hash::make($password ?: Str::random(10)),
                'is_lock' => $this->configService->getMemberLockStatus(),
                'is_active'=>1,
            ]);
            event(new UserRegisterEvent($user->id));

        }
        return CompanyAdministrator::create([
            'uuid'=> 'so'.time().rand(1000, 9999),
            'app_id'=>$user->id,
            'avatar' =>$user->avatar,
            'nick_name' => $user->nick_name,
            'mobile' => $user->mobile,
            'password' => $user->password,

        ]);
    }

    /**
     * @param string $mobile
     * @param int $userId
     *
     * @throws ServiceException
     */
    public function bindMobile(string $mobile, int $userId): void
    {
        $user = User::query()->where('id', $userId)->first();

        if (!$this->businessState->isNeedBindMobile($user->toArray())) {
            throw new ServiceException(__('该账号已绑定手机号'));
        }

        if (User::query()->where('mobile', $mobile)->exists()) {
            throw new ServiceException(__('手机号已存在'));
        }

        $user->mobile = $mobile;
        $user->save();
    }

    /**
     * 更换手机号
     *
     * @param integer $userId
     * @param string $mobile
     * @return void
     */
    public function changeMobile(int $userId, string $mobile): void
    {
        $exists = $this->findMobile($mobile);
        if ($exists) {
            throw new ServiceException(__('手机号已存在'));
        }
        $user = User::findOrFail($userId);
        $user->mobile = $mobile;
        $user->save();
    }

    /**
     * @param $userId
     * @param $avatar
     */
    public function updateAvatar(int $userId, string $avatar): void
    {
        User::query()->where('id', $userId)->update(['avatar' => $avatar]);
    }

    public function updateBrief(int $userId, string $brief): void
    {
        User::query()->where('id', $userId)->update(['brief_introduce' => $brief]);
    }

    /**
     * @param int $userId
     * @param string $nickname
     * @throws ServiceException
     */
    public function updateNickname(int $userId, string $nickname): void
    {
        $user = $this->find($userId);
        User::query()
            ->where('id', $userId)
            ->update([
                'nick_name' => $nickname,

            ]);
    }

    public function updateNicknameAndAvatar(int $userId, string $nickname, string $avatar): void
    {

        User::query()
            ->where('id', $userId)
            ->update([
                'nick_name' => $nickname,
                'avatar' => $avatar
            ]);
    }

    /**
     * @param array $ids
     * @param array $with
     *
     * @return array
     */
    public function getList(array $ids, array $with = []): array
    {
        return User::with($with)->whereIn('id', $ids)->get()->toArray();
    }


    /**
     * @param int $id
     * @param array $with
     * @return Builder|Builder[]|Collection|Model|null
     */
    public function find(int $id, array $with = [])
    {
        return CompanyAdministrator::query()->with($with)->where('app_id',$id)->first();
    }




    /**
     * @param int $page
     * @param int $pageSize
     *
     * @return array
     */
    public function messagePaginate(int $userId, int $page, int $pageSize): array
    {

        $query = User::find($userId)->notifications()->latest();

        $total = $query->count();
        $data = $query->forPage($page, $pageSize)->get();
        $list = $data->toArray();

        return compact('list', 'total');
    }

    /**
     * @param int $page
     * @param int $size
     *
     * @return array
     */
    public function getUserBuyCourses(int $userId, int $page, int $size): array
    {
        $query = UserCourse::query()->with(['course'])->whereUserId($userId)->orderByDesc('created_at');
        $total = $query->count();
        $list = $query->forPage($page, $size)->get()->toArray();

        return compact('list', 'total');
    }







    public function getUserBuyCombos(int $userId, int $page, int $size): array
    {
        $query = UserCombo::query()->with(['combo:title,id','combo.courses:id,title,user_id,favorite_count,thumbsup_count,created_at,thumb'])->whereUserId($userId)->orderByDesc('created_at');
        $total = $query->count();
        $list = $query->get()->forPage($page, $size)->toArray();

        return compact('list', 'total');
    }

    public function getUserBuyPapers(int $userId, int $page, int $size): array
    {
        $query = UserPaper::query()->with(['paper'])->whereUserId($userId)->orderByDesc('created_at');
        $total = $query->count();
        $list = $query->get()->forPage($page, $size)->toArray();

        return compact('list', 'total');
    }

    public function getUserBuyAnthologies(int $userId, int $page, int $size): array
    {
        $query = UserAnthology::query()->with(['anthology'])->whereUserId($userId)->orderByDesc('created_at');
        $total = $query->count();
        $list = $query->get()->forPage($page, $size)->toArray();

        return compact('list', 'total');
    }

    /**
     * @param int $page
     * @param int $pageSize
     *
     * @return array
     */
    public function getUserBuyGroups(int $userId, int $page, int $pageSize): array
    {
        $query = UserGroup::query()->with(['group'])->whereUserId($userId)->orderByDesc('created_at');

        $total = $query->count();
        $list = $query->forPage($page, $pageSize)->get()->toArray();

        return compact('list', 'total');
    }



    public function getUserFavoriteCategory(): array
    {
        return FavoriteCategory::query()
            ->select('id', 'name', 'favorite_count')
            ->where('user_id', Auth::id())
            ->orderByDesc('created_at')->get()->toArray();

    }

    public function getUserAddresses(): array
    {
        return Address::query()
            ->where('user_id', Auth::id())
            ->orderByDesc('is_default')->get()->toArray();


    }



    /**
     * @param int $userId
     * @param int $courseId
     * @return bool
     */
    public function hasCourse(int $userId, int $courseId): bool
    {
        return UserCourse::whereUserId($userId)->whereCourseId($courseId)->exists();
    }

    public function hasCombo(int $userId, array $comboIds): bool
    {
        return UserCombo::whereUserId($userId)->whereIn('combo_id', $comboIds)->exists();
    }

    public function hasBuyCombo(int $userId, int $comboId): bool
    {
        return UserCombo::whereUserId($userId)->where('combo_id', $comboId)->exists();
    }

    public function hasBuyGroup(int $userId, int $groupId): bool
    {
        return UserGroup::whereUserId($userId)->where('group_id', $groupId)->exists();
    }
    public function hasAnthology(int $userId, int $anthologyId): bool
    {
        return UserAnthology::whereUserId($userId)->whereAnthologyId($anthologyId)->exists();
    }

    public function hasGroup(int $userId, array $groupIds): bool
    {
        $now = Carbon::now();

        $record = UserGroup::where('user_id', $userId)
            ->whereIn('group_id', $groupIds)
            ->where('expired_at', '>=', $now)
            ->first();

        return $record !== null;
    }

    public function getUserPrizes(int $userId, int $page, int $size): array
    {
        $query = UserPrize::query()
            ->whereUserId($userId)
            ->orderByDesc('created_at');

        $total = $query->count();
        $list = $query->forPage($page, $size)->get()->toArray();

        return compact('list', 'total');
    }

    public function getUserNotes(int $userId, string $keywords, int $videoId, int $page, int $size): array
    {

        $query = Note::query()
            ->with(['video'])
            ->when($videoId, function ($query) use ($videoId) {
                $query->where('video_id', $videoId);
            })
            ->when($keywords, function ($query) use ($keywords) {
                return $query->where('title', 'like', '%' . $keywords . '%');
            })
            ->whereUserId($userId)
            ->orderByDesc('created_at');

        $total = $query->count();
        $list = $query->forPage($page, $size)->get()->toArray();

        return compact('list', 'total');

    }

    public function getUserCourseNotes(int $userId, int $courseId, int $page, int $size): array
    {
        $query = Note::query()
            ->whereCourseId($courseId)
            ->whereUserId($userId)
            ->orderByDesc('created_at');

        $total = $query->count();
        $list = $query->forPage($page, $size)->get()->toArray();

        return compact('list', 'total');

    }

    public function getUserNoteCourse(array $courseIds, int $page, int $size): array
    {
        $query = Course::query()
            ->withCount(['notes'])
            ->whereIn('id', $courseIds)
            ->orderByDesc('created_at');

        $total = $query->count();
        $list = $query->forPage($page, $size)->get()->toArray();

        return compact('list', 'total');

    }

    public function getUserDoubts(string $type, string $userId, int $page, int $size): array
    {
        $query = Doubt::query()
            ->with(['author', 'student', 'recommends'])
            ->where($type, $userId)
            ->orderByDesc('created_at');

        $total = $query->count();
        $list = $query->forPage($page, $size)->get()->toArray();
        return compact('list', 'total');


    }

    public function getUserSolutions(int $userId, string $type, int $page, int $size): array
    {
        $query = Solution::query()
            ->with(['user', $type, $type . '.user'])
            ->whereUserId($userId)
            ->when($type, function ($query) use ($type) {
                $query->where('solutionable_type', "App\Services\Business\Models\\" . ucfirst($type));
            })
            ->orderByDesc('created_at');

        $total = $query->count();
        $list = $query->forPage($page, $size)->get()->toArray();
        return compact('list', 'total');


    }

    public function getUserVideos(int $userId, int $page, int $size): array
    {
        $query = Video::query()->whereUserId($userId)->orderByDesc('created_at');

        $total = $query->count();
        $list = $query->forPage($page, $size)->get()->toArray();

        return compact('list', 'total');
    }

    public function getUserCourses(int $userId, int $page, int $size): array
    {
        $query = Course::query()
            ->whereUserId($userId)
            ->orderByDesc('created_at');

        $total = $query->count();
        $list = $query->forPage($page, $size)->get()->toArray();

        return compact('list', 'total');
    }

    public function getUserCombos(int $userId, int $page, int $size): array
    {
        $query = Combo::query()
            ->whereUserId($userId)
            ->orderByDesc('created_at');

        $total = $query->count();
        $list = $query->forPage($page, $size)->get()->toArray();

        return compact('list', 'total');
    }


    public function getUserArticles(int $userId, int $page, int $size): array
    {
        $query = Article::query()->whereUserId($userId)->orderByDesc('created_at');
        $total = $query->count();
        $list = $query->forPage($page, $size)->get()->toArray();

        return compact('list', 'total');
    }


    public function getUserAnthologies(int $userId, int $page, int $size): array
    {
        $query = Anthology::query()
            ->whereUserId($userId)
            ->orderByDesc('created_at');
        $total = $query->count();
        $list = $query->forPage($page, $size)->get()->toArray();

        return compact('list', 'total');
    }

    public function getUserPapers(int $userId, int $page, int $size): array
    {
        $query = Paper::query()
            ->whereUserId($userId)
            ->orderByDesc('created_at');
        $total = $query->count();
        $list = $query->forPage($page, $size)->get()->toArray();

        return compact('list', 'total');
    }

    public function getUserQuestions(int $userId, int $page, int $size): array
    {
        $query = Question::query()
            ->whereUserId($userId)
            ->orderByDesc('created_at');
        $total = $query->count();
        $list = $query->forPage($page, $size)->get()->toArray();

        return compact('list', 'total');
    }

    /**
     * @param int $userId
     * @param int $articleId
     * @return bool
     */
    public function hasArticle(int $userId, int $articleId): bool
    {
        return UserArticle::whereUserId($userId)->whereArticleId($articleId)->exists();
    }


    /**
     * @param int $userId
     * @param int $videoId
     * @return bool
     */


    /**
     * @param int $userId
     * @param int $roleId
     * @param int $shopId
     * @param string $expiredAt
     */
    public function changeRole(int $userId, int $roleId,int $shopId, string $expiredAt): void
    {
        $record =  UserRole::query()->where('user_id',$userId)->where('role_id',$roleId)->first();
        if (!$record) {
            UserRole::create([
                'user_id'=>$userId,
                'company_id'=>$shopId,
                'role_id' => $roleId,
                'expired_at' => Carbon::parse($expiredAt),
            ]);
        }
        UserRole::whereId($userId)->update([
            'role_id' => $roleId,
            'expired_at' => Carbon::parse($expiredAt),
        ]);
    }



    /**
     * @param int $page
     * @param int $pageSize
     * @return array
     */
    public function inviteUsers(int $page, int $pageSize): array
    {
        $query = User::whereInviteUserId(Auth::id())->orderByDesc('id');
        $total = $query->count();
        $list = $query->forPage($page, $pageSize)->get()->toArray();

        return compact('list', 'total');
    }

    /**
     * @param int $id
     * @param $userId
     * @param int $reward
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function updateInviteUserId(int $id, $userId, $reward = 0): void
    {
        $inviteConfig = $this->configService->getMemberInviteConfig();
        $expiredDays = $inviteConfig['effective_days'] ?? 0;
        User::whereId($id)->update([
            'invite_user_id' => $userId,
            'invite_user_expired_at' => $expiredDays ? Carbon::now()->addDays($expiredDays) : null,
        ]);
        /**
         * @var $userInviteBalanceService UserInviteBalanceService
         */
        $userInviteBalanceService = app()->make(UserInviteBalanceServiceInterface::class);
        $userInviteBalanceService->createInvite($userId, $reward);
    }

    /**
     * @param int $userId
     * @return int
     */
    public function getUserCourseCount(int $userId): int
    {
        return (int)UserCourse::query()->where('user_id', $userId)->count();
    }


    /**
     * @param int $userId
     * @param int $inc
     */
    public function inviteBalanceInc(int $userId, int $inc): void
    {
        User::find($userId)->increment('invite_balance', $inc);
    }

    /**
     * @param int $userId
     * @param string $id
     */
    public function notificationMarkAsRead(int $userId, string $id): void
    {
        $notification = User::find($userId)->notifications()->whereId($id)->first();
        $notification && $notification->markAsRead();
    }

    /**
     * @param int $userId
     */
    public function notificationMarkAllAsRead(int $userId): void
    {
        User::find($userId)->unreadNotifications->markAsRead();
    }

    /**
     * 未读消息数量
     *
     * @param integer $userId
     * @return int
     */
    public function unreadNotificationCount(int $userId): int
    {
        return (int)User::find($userId)->unreadNotifications->count();
    }

    /**
     * 未读动态数量
     *
     * @param integer $userId
     * @return int
     */
    public function unreadFeedCount(int $userId): int
    {
        $user = User::find($userId);
        $followingids  = $user->followings()->pluck('following_id')->toArray();
        return (int) Activity::query()->whereIn('user_id',$followingids)->whereBetween('created_at',[$user['last_follow_updated_at'],Carbon::now()])->count();
    }

    /**
     * @param int $userId
     * @param int $resourseId
     * @return int
     */


    public function isClaimedCode(int $userId, int $codeId): bool
    {
        return UserRedeemCode::whereRedeemCodeId($codeId)->whereUserId($userId)->exists();
    }

    public function isFollowed(int $followerId, int $followingId): bool
    {
        return Follow::whereFollowerId($followerId)->whereFollowingId($followingId)->exists();
    }

    public function isFavorited(int $userId, int $favorableId, string $favorableType): bool
    {
        return Favorite::whereUserId($userId)->whereFavorableId($favorableId)->whereFavorableType($favorableType)->exists();
    }

    public function isThumbsuped(int $userId, int $thumbsableId, string $thumbsableType): bool
    {
        return ThumbsUp::whereUserId($userId)->whereThumbsupableId($thumbsableId)->whereThumbsupableType($thumbsableType)->exists() ;
    }


    /**
     * 用户视频观看记录
     *
     * @param int $userId
     * @param int $courseId
     * @param int $videoId
     * @param int $duration
     * @param bool $isWatched
     */
    public function recordUserVideoWatch(int $userId, int $courseId, int $videoId, int $duration, bool $isWatched): void
    {
        $record = UserVideoWatchRecord::query()
            ->where('user_id', $userId)
            ->where('course_id', $courseId)
            ->where('video_id', $videoId)
            ->first();

        if ($record) {
            if ($record->watched_at === null && $record->watch_seconds <= $duration) {
                // 如果有记录[没看完 && 当前时间超过已记录的时间]
                $data = ['watch_seconds' => $duration];
                $isWatched && $data['watched_at'] = Carbon::now();
                $record->fill($data)->save();
            }
        } else {
            UserVideoWatchRecord::create([
                'user_id' => $userId,
                'course_id' => $courseId,
                'video_id' => $videoId,
                'watch_seconds' => $duration,
                'watched_at' => $isWatched ? Carbon::now() : null,
            ]);
        }

        // 视频看完event
        $isWatched && event(new UserVideoWatchedEvent($userId, $videoId));
    }

    /**
     * 获取用户视频观看记录
     * @param int $userId
     * @param int $courseId
     * @return array
     */
    public function getUserVideoWatchRecords(int $userId, int $courseId): array
    {
        $records = UserVideoWatchRecord::query()->where('user_id', $userId)->where('course_id', $courseId)->get();
        return $records->toArray();
    }

    /**
     * 获取课程的最新一条观看记录
     * @param int $userId
     * @param int $courseId
     * @return array
     */
    public function getLatestRecord(int $userId, int $courseId): array
    {
        $record = UserVideoWatchRecord::query()->where('user_id', $userId)->where('course_id', $courseId)->orderByDesc('updated_at')->first();
        return $record ? $record->toArray() : [];
    }

    /**
     * @param int $id
     */
    public function setUsedPromoCode(int $id): void
    {
        User::query()->where('id', $id)->update(['is_used_promo_code' => 1]);
    }

    /**
     * @param int $id
     * @param string $ip
     */
    public function setRegisterIp(int $id, string $ip): void
    {
        User::query()->where('id', $id)->update(['register_ip' => $ip]);
    }

    /**
     * @param int $id
     * @param string $area
     */
    public function setRegisterArea(int $id, string $area): void
    {
        $area && User::query()->where('id', $id)->update(['register_area' => $area]);
    }

    /**
     * 重置会员过期用户
     *
     * @return int
     */
    public function resetRoleExpiredUsers(): int
    {
        return User::query()
            ->where('expired_at', '<=', Carbon::now())
            ->update(['role_id' => 0, 'expired_at' => null]);
    }

    /**
     * 用户登录记录
     *
     * @param int $userId
     * @param string $platform
     * @param string $ip
     * @param string $at
     */
    public function createLoginRecord(int $userId, string $platform, string $ip, string $at): void
    {
        $record = UserLoginRecord::create([
            'user_id' => $userId,
            'ip' => $ip,
            'area' => '',
            'platform' => $platform,
            'at' => $at,
        ]);

        User::query()->where('id', $userId)->update(['last_login_id' => $record->id]);
    }

    /**
     * @param int $userId
     * @param string $platform
     * @return array
     */
    public function findUserLastLoginRecord(int $userId, string $platform): array
    {
        $record = UserLoginRecord::query()
            ->where('user_id', $userId)
            ->when($platform, function ($query) use ($platform) {
                $query->where('platform', $platform);
            })
            ->orderByDesc('id')
            ->first();
        return $record ? $record->toArray() : [];
    }

    /**
     * 用户视频观看时间统计
     * @param int $userId
     * @param int $seconds
     */
    public function watchStatSave(int $userId, int $seconds): void
    {
        $year = date('Y');
        $month = date('m');
        $day = date('d');
        $record = UserWatchStat::query()
            ->where('user_id', $userId)
            ->where('year', $year)
            ->where('month', $month)
            ->where('day', $day)
            ->first();
        if ($record) {
            // todo 用户量大了之后此处频繁写入MySQL的CPU会飚高
            UserWatchStat::query()
                ->where('id', $record['id'])
                ->where('seconds', $record['seconds'])
                ->update(['seconds' => $record['seconds'] + $seconds]);
        } else {
            UserWatchStat::create([
                'user_id' => $userId,
                'year' => $year,
                'month' => $month,
                'day' => $day,
                'seconds' => $seconds,
            ]);
        }
    }

    /**
     * @param int $userId
     * @return array
     */
    public function getProfile(int $userId): array
    {
        $profile = UserProfile::query()->where('user_id', $userId)->first();
        return $profile ? $profile->toArray() : [];
    }

    /**
     * @param int $userId
     * @param array $profileData
     */
    public function saveProfile(int $userId, array $profileData): void
    {
        $updateData = [];
        foreach (UserProfile::EDIT_COLUMNS as $column) {
            if (!isset($profileData[$column])) {
                continue;
            }
            if ($profileData[$column] !== null) {
                $updateData[$column] = $profileData[$column];
            }
        }

        $profile = UserProfile::query()->where('user_id', $userId)->first();
        if ($profile) {
            $profile->fill($updateData)->save();
        } else {
            $updateData['user_id'] = $userId;
            UserProfile::create($updateData);
        }
    }

    public function createPorfile(int $userId): void
    {

        $updateData['user_id'] = $userId;
        UserProfile::create($updateData);

    }

    public function getUserWatchStatForYear(int $userId, int $year): int
    {
        return (int)UserWatchStat::query()
            ->where('user_id', $userId)
            ->where('year', $year)
            ->sum('seconds');
    }

    public function getUserWatchStatForMonth(int $userId, int $year, int $month): int
    {
        return (int)UserWatchStat::query()
            ->where('user_id', $userId)
            ->where('year', $year)
            ->where('month', $month)
            ->sum('seconds');
    }

    /**
     * @param int $userId
     * @param int $year
     * @param int $month
     * @param int $day
     * @return int
     */
    public function getUserWatchStatForDay(int $userId, int $year, int $month, int $day): int
    {
        return (int)UserWatchStat::query()
            ->where('user_id', $userId)
            ->where('year', $year)
            ->where('month', $month)
            ->where('day', $day)
            ->sum('seconds');
    }

    /**
     * @param int $userId
     * @return int
     */
    public function inviteCount(int $userId): int
    {
        return (int)User::query()->where('invite_user_id', $userId)->count();
    }

    //关注人数
    public function followingCount(int $followerId): int
    {
        return (int)Follow::query()->where('follower_id', $followerId)->count();
    }

    //粉丝人数
    public function followerCount(int $followingId): int
    {
        return (int)Follow::query()->where('following_id', $followingId)->count();
    }
    public function followingIds(int $followerId): array
    {
        return (array)Follow::query()->where('follower_id', $followerId)->pluck('following_id')->toArray();
    }

    public function isRole(int $userId): bool
    {
        $user = User::query()->find($userId);
        if (!$user['role_id'] || !$user['expired_at']) {
            return false;
        }
        if (Carbon::now()->gt($user['expired_at'])) {
            return false;
        }
        return true;

    }

    /**
     * @param int $videoId
     */
    public function clearVideoWatchRecords(int $videoId)
    {
        UserVideoWatchRecord::query()->where('video_id', $videoId)->delete();
    }

    public function isSuper()
    {

        return  CompanyAdministratorRoleRelation::query();

    }





}
